<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
	public function _initLoader() {
		$this->setAppNamespace('Agitum');
		$autoloader = Zend_Loader_Autoloader::getInstance();
		$autoloader->registerNamespace("Agitum");
		$autoloader->registerNamespace("Dklab");
	}

	public function _initConfig()
    {
    	Zend_Registry::set('Zend_Config', new Zend_Config($this->getOptions()));
    }
    
    public function _initLog() 
    {
        $log = Zend_Log::factory(Zend_Registry::get('Zend_Config')->log->toArray());
        Zend_Registry::set('Zend_Log', $log);
    }

    protected function _initDate()
    {
    	date_default_timezone_set(Zend_Registry::get('Zend_Config')->settings->application->datetime);
    }

	public function _initLocale()
	{
		$locale = new Zend_Locale(Zend_Registry::get('Zend_Config')->locale->default);
		Zend_Registry::set('Zend_Locale', $locale);
	}

	public function _initCache() {
		// Инициализация соединения с memcached
        // конфиг мемкеша

		$cache = new stdClass();

		// Backend для мультизагрузки ключей
		$cache->memcached = new Dklab_Cache_Backend_MemcachedMultiload (Zend_Registry::get('Zend_Config')->memcached->toArray());

		// Глобальное пространство имен кеша
		$cache->global = new Dklab_Cache_Backend_NamespaceWrapper(
			new Dklab_Cache_Backend_TagEmuWrapper ($cache->memcached),
			'global'
		);
		// пространство имен для кеша метаданных Zend_Db_Table
		$cache->database = new Dklab_Cache_Backend_NamespaceWrapper(
			new Dklab_Cache_Backend_TagEmuWrapper ($cache->memcached),
			'database'
		);
		// пространство имен для кеша сессий
		$cache->session = new Dklab_Cache_Backend_NamespaceWrapper(
			new Dklab_Cache_Backend_TagEmuWrapper ($cache->memcached),
			'session'
		);

		// сохраняем в реестр
		Zend_Registry::set('Zend_Cache', $cache);
	}

	public function _initDb() {
		$e = null;
		try {
			$db = Zend_Db::factory(Zend_Registry::get('Zend_Config')->db);
			$db->setFetchMode(Zend_DB::FETCH_ASSOC);
			$db->getConnection();
			
			Zend_Db_Table_Abstract::setDefaultAdapter($db);
			Zend_Registry::set('Zend_Db', $db);
		} catch (PDOException $e) {
		} catch (Zend_Db_Adapter_Exception $e) {
		} catch (Zend_Exception $e) {
		}
		
		if ( $e ) {
			if ( $e->getCode() == 7 ) {
				echo 'Could not connect to database';
			} else {
				$e->getMessage();
			}
			exit();
		}

		// Инициализация Zend_Cache для метаданных Zend_Db_Table
		$dbcache = Zend_Cache::factory('Core', Zend_Registry::get('Zend_Cache')->database, array('automatic_serialization' => true));
		Zend_Db_Table_Abstract::setDefaultMetadataCache($dbcache);
	}

	public function _initSession() 
	{
		// Хранение сессий в кеше
        $handler = new Agitum_Session_SaveHandler_Cache();
        $handler->setCache(Zend_Registry::get('Zend_Cache')->session);

        Zend_Session::setSaveHandler($handler);
        Zend_Session::setOptions(
        	array(
        		'name' => 'TTSID',
        		'remember_me_seconds' => 864000,
        		'gc_maxlifetime' => 864000
        	)
        );
        // Старт сессии
        Zend_Session::start();
	}
	
	public function _initMessaging() 
	{
		$cfg = Zend_Registry::get('Zend_Config');
		$transport = null;
		switch($cfg->mail->transport->type) {
			case 'smtp': {
				$transport = new Zend_Mail_Transport_Smtp($cfg->mail->smtp->host, $cfg->mail->smtp->options->toArray());
				break;
			}
			case 'file': {
				$transport = new Zend_Mail_Transport_File($cfg->mail->file->options->toArray());
				break;
			}
			default: {
				$opt = $cfg->mail->sendmail->options ? $cfg->mail->sendmail->options->toArray() : array();
				$transport = new Zend_Mail_Transport_Sendmail($opt);
				break;
			}
		}
		Zend_Mail::setDefaultFrom($cfg->mail->from);
		Zend_Mail::setDefaultReplyTo($cfg->mail->replyto);
		Zend_Mail::setDefaultTransport($transport);
		Zend_Registry::set('Zend_Mail_Transport', $transport);
		
		$smsGate = Agitum_Sms_Gate::factory($cfg->sms->gate, $cfg->sms->options );
		Zend_Registry::set('Agitum_Sms_Gate', $smsGate);
	}
	
	public function _initFrontController() 
	{
		$options = Zend_Registry::get('Zend_Config')->frontController;
		$front = Zend_Controller_Front::getInstance();
		
		$front->setParams($options->params->toArray());
		$front->addModuleDirectory($options->moduleDirectory);
		$front->setDefaultAction($options->defaultaction);
		$front->setDefaultControllerName($options->defaultcontrollername);
		$front->setDefaultModule($options->defaultmodule);
		
		return $front;
	}

	public function _initRoute()
	{
		$routes = null;
		$slot = new Agitum_Model_Cache_Slot_Route_List();
		$routes = $slot->load();
        if ( !$routes ) {
        	$obj = new Agitum_Model_Route();
        	list($ids, $routes) = $obj->getRouteList();
        	foreach ( $ids as $i => $id ) {
        		$slot->addTag( new Agitum_Model_Cache_Tag_Route($id) );
        	}
        	$slot->addTag(new Agitum_Model_Cache_Tag_Route_List() );
        	$slot->save($routes);
        }
        
        $front = Zend_Controller_Front::getInstance();
        $router = $front->getRouter();
        $router->removeDefaultRoutes();
        $router->addRoutes($routes);
	}
	
	public function _initLayout() 
	{
		 $opt = $this->getOption('layouts');
        // Настройка вида.
        Zend_Layout::startMvc( array(
            'layoutPath' => $opt['path'],
            'layout' => $opt['default']
        ) );
	}

	public function _initView() 
	{
		// Инициализия View

	    $options = $this->getOptions('view');
	    $view = new Zend_View($options);

	    if(isset($options['doctype'])) {
	        $view->doctype()->setDoctype(strtoupper($options['doctype']));
        }

        $view->headTitle($this->getOption('title'))
             ->setSeparator(' :: ');

        $view->env = $this->getEnvironment();
		$view->addScriptPath(APPLICATION_PATH.'/views');
		$view->addHelperPath(APPLICATION_PATH.'/../library/Agitum/View/Helper', 'Agitum_View_Helper_');
        
		$renderer = new Zend_Controller_Action_Helper_ViewRenderer();
        $renderer->setView($view);

        Zend_Controller_Action_HelperBroker::addHelper($renderer);
        Zend_Registry::set('Zend_View', $view);
        return $view;
    }

	public function _initApplication() 
	{

		$loader = new Zend_Loader_PluginLoader(array(
    		'Agitum_Application_Resource_' => 'Agitum/Application/Resource',
			'Agitum_Controller_Action_Helper_' => 'Agitum/Application/Resource',
			'Agitum_Form_' => 'Agitum/Form',
			'Agitum_View_' => 'Agitum/View',
			'Agitum_Validate_' => 'Agitum/Validate',
		 	'Zend_Application_Resource_' => 'Zend/Application/Resource'
		));
		$this->setPluginLoader($loader);
		
		

		Zend_Controller_Action_HelperBroker::addHelper(new Agitum_Controller_Action_Helper_FormLoader($loader));

		$front = Zend_Controller_Front::getInstance();

        $front->registerPlugin(new Agitum_Controller_Plugin_Acl());
        $front->registerPlugin(new Agitum_Controller_Plugin_Navigation());
        $front->registerPlugin(new Agitum_Controller_Plugin_IdentityLoader());
		$front->registerPlugin(new Agitum_Controller_Plugin_AccessCheck());
		
    }
}

/*

=== Zend_Controller_Router_Route ===

$route = new Zend_Controller_Router_Route(
    'archive/:year/*', 			// шаблон URI
    array(
        'year'       => 2006,	// значения по-умолчанию
        'controller' => 'archive',
        'action'     => 'show'
    ),
    array('year' => '\d+') // требования к переменным
);


По умолчанию действует правило, все что явно не разрешено - то запрещено.
Роль - не наследуется.
Пользователь получает Роли через Группу, в которой он состоит.
Каждый Пользователь может иметь персональную Роль.
Персональная Роль имеет приоритет перед Ролями полученными через Группу.
Нет приоритета среди Ролей, полученных через Группу т.е. Групповые Роли равноправны.
Роль по умолчанию - guest (если у Пользователя нет явных Ролей, то считается что у него есть Роль guest)
Если у Пользователя есть Роль, отличная от guest, то Роль guest может быть удалена, в таком случае имеют силу только назначенные явно Роли.
Одну и ту же Роль могут иметь несколько Групп и Пользователей
Количество Ролей, Ресурсов и Привилегий не ограничено
Разрешение на доступ ищется среди всех ролей. Как только находится первое правило, разрешающее доступ, поиск прекращается - доступ разрешен. Если ничего не найдено - то доступ запрещен.
Если доступ запрещен в Персональной Роли, то проверка Групповых ролей не производится - Доступ запрещен.
Разрешено наследование Ресурсов (при этом наследуются все привилегии родителя)
Ресурс может иметь только одного родителя (дерево)



 */

